package com.wenlin.myproduction.widget;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.ColorInt;
import androidx.annotation.Nullable;

import com.wenlin.myproduction.R;
import com.wenlin.myproduction.bean.ScheduleContentClickBean;
import com.wenlin.myproduction.bean.ScheduleRecordBean;
import com.wenlin.myproduction.util.Checker;
import com.wenlin.myproduction.util.RegexUtils;
import com.wenlin.myproduction.util.TypeData;
import com.wenlin.myproduction.util.TypeDataNames;
import com.wenlin.myproduction.util.UI;

import org.greenrobot.eventbus.EventBus;

import java.util.List;
import java.util.Locale;

/**
 * @author 文琳_377979485@qq.com
 * @time 2021/10/15 0015 上午 10:57
 * @desc 涉及到各种RecyclerView的嵌套，所以需要自定义控件显示排班内容，带删除按钮。
 */
public class ScheduleContentView extends View {
    private Paint paint, paintLine;
    private TextPaint textPaint, textPaintSmall;
    private Rect rect, rectSmall;
    @ColorInt
    private int colorBlue = Color.parseColor("#ff0A76F5");
    @ColorInt
    private int colorBlack = Color.parseColor("#ff333333");
    @ColorInt
    private int colorRed = Color.parseColor("#ffff3333");
    @ColorInt
    private int colorWhite = Color.parseColor("#ffffffff");
    @ColorInt
    private int colorDivider = Color.parseColor("#ffdddddd");
    private static final float ITEM_WIDTH = UI.getPx(R.dimen.wpx168);
    private static final float ITEM_HEIGHT = UI.getPx(R.dimen.wpx77);
    private static final float PLUS_LONG = UI.getPx(R.dimen.wpx10);
    private static final float DELETE_RADIUS = UI.getPx(R.dimen.wpx15);
    private static final float DELETE_LONG = UI.getPx(R.dimen.wpx6);
    private static final float HORIZONTAL_MARGIN = UI.getPx(R.dimen.wpx4);
    private static final float VERTICAL_MARGIN = UI.getPx(R.dimen.wpx4);
    private static final float LINE_WIDTH = UI.getPx(R.dimen.wpx2);
    private static final float MAX_CLICK_DISTANCE = 5;//点击时，手指抬起和手指落下时的距离差，在一定范围内才看做点击，否则看成拖动，拖动不处理

    private ScheduleRecordBean.ListsDTO bean;
    private boolean isEdit;
    private boolean showHelper;
    private float lastX, lastY;

    public ScheduleContentView(Context context) {
        this(context, null);
    }

    public ScheduleContentView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    /**
     * 初始化
     */
    private void init() {
        paint = new Paint();
        paint.setStyle(Paint.Style.FILL_AND_STROKE);
        paint.setAntiAlias(true);
        paint.setDither(true);

        paintLine = new Paint();
        paintLine.setStyle(Paint.Style.STROKE);
        paintLine.setAntiAlias(true);
        paintLine.setStrokeWidth(LINE_WIDTH);
        paintLine.setStrokeCap(Paint.Cap.ROUND);
        paintLine.setDither(true);

        textPaint = new TextPaint();
        textPaint.setAntiAlias(true);
        textPaint.setDither(true);
        textPaint.setTextSize(UI.getPx(R.dimen.wpx28));
        textPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        textPaint.setColor(colorBlack);

        textPaintSmall = new TextPaint();
        textPaintSmall.setAntiAlias(true);
        textPaintSmall.setDither(true);
        textPaintSmall.setTextSize(UI.getPx(R.dimen.wpx24));
        textPaintSmall.setStyle(Paint.Style.FILL_AND_STROKE);
        textPaintSmall.setColor(colorRed);

        rect = new Rect();
        rectSmall = new Rect();
    }

    /**
     * 设置数据
     *
     * @param bean 表格数据
     */
    public void setData(ScheduleRecordBean.ListsDTO bean) {
        this.bean = bean;
        postInvalidate();
    }

    /**
     * 设置是否是编辑模式，如果是编辑模式则显示删除按钮
     *
     * @param isEdit 是否是编辑模式
     */
    public void setIsEdit(boolean isEdit) {
        this.isEdit = isEdit;
        postInvalidate();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //画横向分割线
        paintLine.setColor(colorDivider);
        canvas.drawLine(0, ITEM_HEIGHT - LINE_WIDTH / 2f, getWidth(), ITEM_HEIGHT - LINE_WIDTH / 2f, paintLine);
        if (Checker.isNull(bean)) return;
        List<String> listSchedule = bean.getSchedule_arr();
        List<Integer> listNight = bean.getIs_night_arr();
        List<String> listDuration = bean.getDrt_arr();
        if (listSchedule.size() > 0 && listSchedule.size() == listNight.size() && listSchedule.size() == listDuration.size()) {
            //画主体内容
            for (int i = 0; i < listSchedule.size(); i++) {
                String str = listSchedule.get(i);
                float startX = i * ITEM_WIDTH;
                float centerY = ITEM_HEIGHT / 2f;
                //画竖向分割线
                paintLine.setColor(colorDivider);
                canvas.drawLine((i + 1) * ITEM_WIDTH - LINE_WIDTH / 2f, 0, (i + 1) * ITEM_WIDTH - LINE_WIDTH / 2f, ITEM_HEIGHT, paintLine);
                if (Checker.hasWord(str)) {
                    float maxWidth;
                    float margin;
                    //画文字
                    if (str.contains("span")) {//带调休标签，要画两行
                        String[] arr = {"", ""};
                        str = str.replaceAll("<\\/span>", "");
                        if (str.contains("<span class=\"red\">")) {
                            arr = str.split("<span class=\"red\">");
                        }
                        boolean hasSecondLine = arr.length >= 2 && Checker.hasWord(arr[1]);
                        textPaint.getTextBounds(arr[0], 0, arr[0].length(), rect);
                        if (hasSecondLine) {
                            textPaintSmall.getTextBounds(arr[1], 0, arr[1].length(), rectSmall);
                            maxWidth = Math.max(rect.width(), rectSmall.width());
                            margin = (ITEM_WIDTH - maxWidth - (isEdit ? HORIZONTAL_MARGIN + 2 * DELETE_RADIUS : 0)) / 2f;
                            canvas.drawText(arr[1], startX + margin + maxWidth / 2f - rectSmall.width() / 2f, ITEM_HEIGHT / 2f + VERTICAL_MARGIN / 2f + rectSmall.height() / 2f - (rectSmall.bottom + rectSmall.top) / 2f, textPaintSmall);
                        } else {
                            maxWidth = rect.width();
                            margin = (ITEM_WIDTH - maxWidth - (isEdit ? HORIZONTAL_MARGIN + 2 * DELETE_RADIUS : 0)) / 2f;
                        }
                        canvas.drawText(arr[0], startX + margin + maxWidth / 2f - rect.width() / 2f, hasSecondLine ? centerY - VERTICAL_MARGIN / 2f - rect.height() / 2f - (rect.bottom + rect.top) / 2f : centerY - (rect.bottom + rect.top) / 2f, textPaint);
                    } else {//只有一行
                        textPaint.getTextBounds(str, 0, str.length(), rect);
                        maxWidth = rect.width();
                        margin = (ITEM_WIDTH - maxWidth - (isEdit ? HORIZONTAL_MARGIN + 2 * DELETE_RADIUS : 0)) / 2f;
                        canvas.drawText(str, startX + margin + maxWidth / 2f - rect.width() / 2f, centerY - (rect.bottom + rect.top) / 2f, textPaint);
                    }
                    //如果是编辑模式，显示删除按钮
                    if (isEdit) {
                        float deleteCenterX = (i + 1) * ITEM_WIDTH - margin - DELETE_RADIUS;
                        float deleteCenterY = ITEM_HEIGHT / 2f;
                        //画删除按钮
                        paint.setColor(colorRed);
                        canvas.drawCircle(deleteCenterX, centerY, DELETE_RADIUS, paint);
                        paintLine.setColor(colorWhite);
                        canvas.drawLine(deleteCenterX - DELETE_LONG, deleteCenterY - DELETE_LONG, deleteCenterX + DELETE_LONG, deleteCenterY + DELETE_LONG, paintLine);
                        canvas.drawLine(deleteCenterX - DELETE_LONG, deleteCenterY + DELETE_LONG, deleteCenterX + DELETE_LONG, deleteCenterY - DELETE_LONG, paintLine);
                    }
                } else if (isEdit) {//如果内容为空，则不显示，编辑时显示一个蓝色加号
                    paintLine.setColor(colorBlue);
                    canvas.drawLine(startX + ITEM_WIDTH / 2f - PLUS_LONG, centerY, startX + ITEM_WIDTH / 2f + PLUS_LONG, centerY, paintLine);
                    canvas.drawLine(startX + ITEM_WIDTH / 2f, centerY - PLUS_LONG, startX + ITEM_WIDTH / 2f, centerY + PLUS_LONG, paintLine);
                }
            }
            //画夜班数和上班时长的竖向分割线
            paintLine.setColor(colorDivider);
            canvas.drawLine((listSchedule.size() + 1) * ITEM_WIDTH - LINE_WIDTH / 2f, 0, (listSchedule.size() + 1) * ITEM_WIDTH - LINE_WIDTH / 2f, ITEM_HEIGHT, paintLine);
            paintLine.setColor(colorDivider);
            canvas.drawLine((listSchedule.size() + 2) * ITEM_WIDTH - LINE_WIDTH / 2f, 0, (listSchedule.size() + 2) * ITEM_WIDTH - LINE_WIDTH / 2f, ITEM_HEIGHT, paintLine);
            //计算夜班数
            int totalNight = 0;
            for (int i = 0; i < listNight.size(); i++) {
                totalNight += listNight.get(i);
            }
            String strTotalNight = String.valueOf(totalNight);
            textPaint.getTextBounds(strTotalNight, 0, strTotalNight.length(), rect);
            canvas.drawText(strTotalNight, listSchedule.size() * ITEM_WIDTH + ITEM_WIDTH / 2f - rect.width() / 2f, ITEM_HEIGHT / 2f - (rect.bottom + rect.top) / 2f, textPaint);
            //计算总上班时长
            double totalDuration = 0d;
            for (int i = 0; i < listDuration.size(); i++) {
                String s = listDuration.get(i);
                if (RegexUtils.isMatch("^\\d*.?\\d*$", s)) {//检查时长是否是一个数字，是数字才能参与计算，当时长为空或者“”时不会参与计算。
                    try {
                        double d = Double.parseDouble(s);
                        totalDuration += d;
                    } catch (NumberFormatException e) {
                        e.printStackTrace();
                    }
                }
            }
            String strTotalDuration = String.format(Locale.CHINA, "%.2f", totalDuration);
            textPaint.getTextBounds(strTotalDuration, 0, strTotalDuration.length(), rect);
            canvas.drawText(strTotalDuration, (listSchedule.size() + 1) * ITEM_WIDTH + ITEM_WIDTH / 2f - rect.width() / 2f, ITEM_HEIGHT / 2f - (rect.bottom + rect.top) / 2f, textPaint);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        if (event.getAction() == KeyEvent.ACTION_DOWN) {
            lastX = x;
            lastY = y;
            return true;
        } else if (event.getAction() == KeyEvent.ACTION_UP) {
            //如果手指抬起和手指按下的距离太大，超过一定限定值则视为拖动，不做后续的处理
            if (Math.abs(x - lastX) > MAX_CLICK_DISTANCE || Math.abs(y - lastY) > MAX_CLICK_DISTANCE)
                return false;
            if (Checker.isNull(bean)) return false;
            if (Checker.hasNoList(bean.getSchedule_arr())) return false;
            for (int i = 0; i < bean.getSchedule_arr().size(); i++) {
                if (x > ITEM_WIDTH * i && x < ITEM_WIDTH * (i + 1)) {
                    //发送通知给外界，传递一个点击位置和对应的数据对象。外界可以根据数据进行后续的操作，比如ScheduleEditActivity将排班数据删除或者弹窗添加新的排班数据
                    EventBus.getDefault().post(new TypeData<>(TypeDataNames.clickScheduleContentViewOnPosition, new ScheduleContentClickBean(bean, i)));
                    break;
                }
            }
            return true;
        }
        return super.onTouchEvent(event);
    }
}
